package com.ayq.activiti.common.util;

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Maps;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.Map;

/**
 * 返回响应结果 Ret：子程序返回指令（汇编-ret指令用栈中的数据，修改IP的值，从而实现栈转移），为节省高频使用类，设计成简单单词
 *
 * @author admin
 */
@ApiModel(value = "响应结果")
@Data
public class Ret<T> {
  private static final long serialVersionUID = -6190689122701100762L;

  /** 响应编码 */
  @ApiModelProperty(value = "响应编码:1-请求处理成功")
  private int code;
  /** 提示消息 */
  @ApiModelProperty(value = "提示消息")
  private String message;

  /** 请求路径 */
  @ApiModelProperty(value = "请求路径")
  private String path;

  /** 响应数据 */
  @ApiModelProperty(value = "响应数据")
  private T data;

  /** http状态码 */
  private int httpStatus;

  /** 附加数据 */
  @ApiModelProperty(value = "附加数据-响应时间-异常数据等")
  private Map<String, Object> extra;

  /** 当前时间戳 */
  @ApiModelProperty(value = "当前时间戳")
  private long timestamp = System.currentTimeMillis();

  public Ret() {
    super();
  }

  public Ret(T data) {
    this.data = data;
    this.message = ResCode.OK.getMessage();
    this.code = ResCode.OK.getCode();
  }

  public Ret(String message, T data) {
    this.data = data;
    this.message = message;
    this.code = ResCode.OK.getCode();
  }


  public Ret(String message) {
    this.message = message;
    this.code = ResCode.getResultEnum(this.message).getCode();
  }

  public Ret(Integer code, String message) {
    this.message = message;
    this.code = code;
  }

  public Ret(Boolean bool) {
    if (bool) {
      this.message = ResCode.OK.getMessage();
      this.code = ResCode.OK.getCode();
    }else {
      this.message = ResCode.FAIL.getMessage();
      this.code = ResCode.FAIL.getCode();
    }
  }

  public static <T>Ret<T> create() {
    return new Ret<>();
  }

  public int getCode() {
    return code;
  }

  public String getMessage() {
    return message;
  }

  public String getPath() {
    return path;
  }

  public Object getData() {
    return data;
  }

  public Map<String, Object> getExtra() {
    return extra;
  }

  public long getTimestamp() {
    return timestamp;
  }

  @JSONField(serialize = false, deserialize = false)
  @JsonIgnore
  public int getHttpStatus() {
    return httpStatus;
  }

  @JSONField(serialize = false, deserialize = false)
  @JsonIgnore
  public boolean isOk() {
    return this.code == ResCode.OK.getCode();
  }

  @JsonIgnore
  public boolean isFail() {
    return this.code == ResCode.FAIL.getCode();
  }

  public static <T>Ret<T> response(int code) {
    if (code == 0) {
      return new Ret<>(true);
    } else {
      return new Ret<>(false);
    }
  }

  public static <T>Ret<T> responseBySqlResult(int code) {
    if (code == 0) {
      return new Ret<>(true);
    } else {
      return new Ret<>(false);
    }
  }

  public static <T>Ret<T> ok() {
    return new Ret<>(true);
  }


  public static <T>Ret<T> ok(T data) {
    return new Ret<>(data);
  }
  public static <T>Ret<T> ok(String message, T data) {
    return new Ret<>(message,data);
  }

  public static <T>Ret<T> fail() {
    return new Ret<>(false);
  }

  public static <T>Ret<T> error(String msg) {
    return new Ret<>(ResCode.Exception.getCode(),msg);
  }



  public static Ret<Boolean> ok(Boolean bool) {
    return new Ret<>(bool);
  }

//  public Ret<T> data(T data) {
//    return new Ret<>(data);
//  }

  public Ret<T> path(String path) {
    this.path = path;
    return this;
  }

  public Ret<T> httpStatus(int httpStatus) {
    this.httpStatus = httpStatus;
    return this;
  }

  public Ret<T> put(String key, Object value) {
    if (this.extra == null) {
      this.extra = Maps.newHashMap();
    }
    this.extra.put(key, value);
    return this;
  }

  @Override
  public String toString() {
    return "ResultBody{"
        + "code="
        + code
        + ", message='"
        + message
        + '\''
        + ", path='"
        + path
        + '\''
        + ", data="
        + data
        + ", httpStatus="
        + httpStatus
        + ", extra="
        + extra
        + ", timestamp="
        + timestamp
        + '}';
  }



  /**
   * 其他异常处理方法返回的结果
   *
   * @param resCode ResCode
   * @return Ret
   */
  public Ret<T> otherError(ResCode resCode) {
    this.code = ResCode.Exception.getCode();
    this.message = resCode.getMessage();
    return this;
  }

}
